#ifndef FORMATION_H
#define FORMATION_H

//#pragma warning(disable:4786)
#include <stdio.h>

const int UNITS_IN_TEAM = 3;
const int DEF_UNIT = 0;
const int MID_UNIT = 1;
const int FOR_UNIT = 2;

const int UNIT_LINE = 0;
const int UNIT_TWO_LINES = 1;
const int UNIT_STRONG_CENTER = 2;
const int UNIT_CENTER_ATTACK = 3;
const int UNIT_CENTER_DEFENCE = 4;
const int UNIT_2LINES_ATTACK = 5;
const int UNIT_2LINES_DEFENCE = 6;

const int UNIT_NAMES_COUNT = 7;

const int FORMATION_NONE = -1;
const int FORMATION_622 = 0;
const int FORMATION_532 = 1;
const int FORMATION_523 = 2;
const int FORMATION_433 = 3;
const int FORMATION_343 = 4;
const int FORMATION_334 = 5;
 
const int FORMATION_COUNT = 6;

const int UNIT_MAX_PLAYERS = 6;

const int UNIT_WIDTH_MAX = 100;             // max. sirka jednotky (v pocte sektorov)
const int UNIT_HEIGHT_MAX = 200;            // max. vyska jednotky (v pocte sektorov)

const int UNITS_COUNT = 16;
const float UNDEF_POS = -1000.0;


// Nazvy jednotiek :
// prve cislo udava pocet hracov
// L	- hraci su v jednej urovni
// V	- stredny hrac(i) vysunuty k superovi, stiahnute kridla
// OV	- opak V, vysunute kridla, stiahnuty stred
// S	- zosileny stred, akoby dve urovne, kridla v strede
// 23	- formacia pre 5 hracov, 2 x LINE, 2 blizsie k superovi
// 32	- formacia pre 5 hracov, 2 x LINE, 3 blizsie k superovi
// 2L	- dve rovnocene urovne, 2 x LINE

const int UNIT_2_L = 0;

const int UNIT_3_L = 1;
const int UNIT_3_V = 2;
const int UNIT_3_OV = 3;

const int UNIT_4_L = 4;
const int UNIT_4_V = 5;
const int UNIT_4_OV = 6;
const int UNIT_4_S = 7;

const int UNIT_5_L = 8;
const int UNIT_5_23 = 9;
const int UNIT_5_32 = 10;
const int UNIT_5_V = 11;
const int UNIT_5_OV = 12;

const int UNIT_6_2L = 13;
const int UNIT_6_V = 14;
const int UNIT_6_OV = 15;

// sirka jednotky v metroch
const float UNIT_WIDTH = 1.0f; // zmena z 15.0f
const float UNIT_HW = 1.0f;

// relativna x-ova poloha hracov voci lopte, pokial je v strede
const float DEF_ORIGIN_DIST = -30.0f;
const float MID_ORIGIN_DIST = -4.0f;
const float FOR_ORIGIN_DIST = 25.0f;

const int PLAYER_COUNT = 11;

const Point GOALIE_POS = Point( -44.0, 0.0 );

const int SIDE_NONE = 0;
const int SIDE_LEFT = 1;
const int SIDE_RIGHT = -1;


enum FormationRole
{
	PR_GoalKeeper,
	PR_Defensman,
	PR_Midfielder,
	PR_Forward,
	
	PR_Count
};


// Trieda subformacia
class Unit
{
public:
	int m_name;								// nazov formacie
	int m_nPlayerCount;						// pocet hracov v jednotke
	int m_type;								// typ formacie
	Point m_cRelPos[UNIT_MAX_PLAYERS];		// pozicia hracov v jednotke (v metroch)
    	
	//pridane 06.12.04
	float m_cRange[UNIT_MAX_PLAYERS];		// rozsah pokrytia hraca v jednotke (v metroch)
	int m_nWidth;			         	    // sirka jednotky - pocet sektorov
	int m_nHeight;				     		// vyska jednotky - pocet sektorov
    float m_fScale;						    // velkost stvorcoveho sektora v metroch 
	float m_fCoverage[UNIT_HEIGHT_MAX][UNIT_WIDTH_MAX]; // pokrytie jednotlivych sektorov v jednotke

    //pridane 07.03.05
};


class Formation
{
public:
	
	Unit m_cUnits[UNITS_COUNT];
	
	Point m_cRelPos[PLAYER_COUNT];			// sucasna domovska pozicia po zohladeni lopty
	FormationRole m_eRole[FORMATION_COUNT][PLAYER_COUNT];
	
	int m_nTeamSide;
	int m_nFormationId;
//	int m_nUnitDef;
//	int m_nUnitMid;
//	int m_nUnitFor;
	float m_dDefBallDist;
	float m_dMidBallDist;
	float m_dForBallDist;

	Unit * UnitList[100]; // pole smernikov subformacii
	
	int m_nDefUnitID;     // ID sucasnej obrannej subformacie
	int m_nMidUnitID;	  // ID sucasnej strednej subformacie
	int m_nForUnitID;	  // ID sucasnej utocnej subformacie

	int m_nDefUnits;      // pocet jednotiek 
	int m_nMidUnits;
	int m_nForUnits;
	
	float m_mDefOffset;   //posunutie jednotky od laveho okraja ihriska v sektoroch
	float m_mMidOffset;      
	float m_mForOffset;      

	// Konstruktor
	Formation();

	// Destruktor
	~Formation();
	
	//FormationRole GetPlayerRole( int nTeamSide, int nPlayerId );
	//int GetPlayersRoleCount( int nFormationId, FormationRole eRole );
	//int GetUnitId( int nTeamSide, FormationRole eRole );
	//int GetUnitIndex( int nTeamSide, int nPlayerId );
	FormationRole GetPlayerRole(int nPlayerId);
	
	Point AdjustDefPositionX( const Point& player_pos, const Point& ball_pos );
	Point AdjustForPositionX( const Point& player_pos, const Point& ball_pos );
	Point AdjustMidPositionX( const Point& player_pos, const Point& ball_pos );
	Point AdjustXPosition( int nTeamSide, int nPlayerId, const Point& cOriginPos, const Point& cBallPos );
	Point AdjustYPosition( int nTeamSide, int nPlayerId, const Point& cOriginPos, const Point& cBallPos );
	Point GetPlayerPosInUnit(int nFormation, int nPlayer); 
	Point GetPlayerPosition( int nPlayerId, const Point& cBallPos );
	Point GetPlayerPosition( int nTeamSide, int nPlayerId );
	Point GetPlayerPosition( int nTeamSide, int nPlayerId, const Point& cBallPos, bool followx, bool followy );
	Point GetUnitDimensions(int nFormation);
	Point GetUnitPosition( int nTeamSide, int nPlayerId );
	
	float GetUnitOffset(int nFormation);
	float GetUnitWidth(int nFormation);
	
	int GetUnitId(FormationRole eRole );
	int GetPlayersCountInUnit(int nFormation);
	int GetUnitFromRawUnit( int nPlayerCount, int nRawUnit );
	int GetUnitIndex(int nPlayerId );
	int GetUnitsCount(int type = 0); // typ = 1 - obrana, 2 - stred, 3 - utok
	
	void GetUnitCoverage(int nFormation, float (* fCoverage)[11] );
	void GetUnits(int & nDefUnitID, int & nMidUnitID, int & nForUnitID);
	void Init( int nTeamSide, int nFormationId, int nDefUnit, int nMidUnit, int nForUnit );
	void InitRawUnits( int nTeamSide, int nFormationId, int nDefUnit, int nMidUnit, int nForUnit );
  bool ReadConfigLine(FILE * file, char * parameter, char * values);
	void ParseConfig();
	void SetSide( int side ) { m_nTeamSide = side; }
	void SetUnitOffset(float offset, int type = 0);
	void SetUnits(int nDefUnitID, int nMidUnitID, int nForUnitID);
};


#endif // FORMATION_H
